#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string>
#include <strings.h>
#include <cstring>
#include <fcntl.h>
#include "mythread.hpp"

void Usage(char *argv[])
{
    printf("%s\n\t[IP] [Port]", argv[0]);
}

int clientInit(uint16_t port, uint32_t ip, struct sockaddr_in &server_addr)
{
    // 创建套接字
    int sockFd = socket(AF_INET, SOCK_DGRAM, 0);
    if (-1 == sockFd)
    {
        std::cerr << "socket() error, errno: " << errno << "errorstring: " << strerror(errno) << std::endl;
        exit(2);
    }

    // 信息接收方(server)的socket信息
    server_addr.sin_addr.s_addr = ip;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = port;

    return sockFd;
}

// 向服务器发数据
void send_task(int sockfd, const struct sockaddr_in &server_addr, std::string name)
{
    while (true)
    {
        std::string massage;
        printf("%s | massage# ", name.c_str());
        fflush(stdout);
        std::getline(std::cin, massage);

        // 发送数据
        int ret = sendto(sockfd, massage.c_str(), massage.size(), 0, (struct sockaddr *)&server_addr, sizeof(server_addr));
        if (-1 == ret)
        {
            std::cerr << "sendto() error, errno: " << errno << "errorstring: " << strerror(errno) << std::endl;
            exit(3);
        }
    }
}

// 接收数据
void recev_task(int sockfd, std::string name)
{
    int fd = open("/dev/pts/1", O_WRONLY);
    if (fd < 0)
    {
        LOG(FATA, "open error");
        exit(1);
    }

    while (true)
    {
        // 用来记录信息发送方（不一定是server）的socket信息
        struct sockaddr_in all_addr;
        bzero(&all_addr, sizeof(all_addr));
        socklen_t all_addrLen = sizeof(all_addr);

        char buffer[1024] = {0};
        // 接收数据
        recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&all_addr, &all_addrLen);

        std::string outmassage = "\n" + name + " | receve# " + buffer + "\n";
        int n = write(fd, outmassage.c_str(), outmassage.size());
        if (n < 0)
        {
            LOG(ERROR, "write error");
            exit(1);
        }

        //printf("\n%s | receve# %s\n", name.c_str(), buffer);
    }
}

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        Usage(argv);
        exit(1);
    }

    // 获取server的IP和Port
    uint16_t port = htons(std::stoi(argv[2]));
    uint32_t ip = inet_addr(argv[1]);

    struct sockaddr_in server_addr;
    bzero(&server_addr, sizeof(server_addr));

    int sockFd = clientInit(port, ip, server_addr); // 初始化client

    my_thread::mythread client_recev(std::bind(&recev_task, sockFd, std::placeholders::_1), "client_recev");
    my_thread::mythread client_send(std::bind(&send_task, sockFd, server_addr, std::placeholders::_1), "client_send");

    client_recev.Start();
    client_send.Start();

    client_recev.Join();
    client_recev.Join();

    return 0;
}